package com.newear.marathon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.newear.marathon.dto.admin.enumeration.AdminStatus;
import com.newear.marathon.dto.admin.inquiry.*;
import com.newear.marathon.dto.admin.maintenance.*;
import com.newear.marathon.entity.admin.AdminRole;
import com.newear.marathon.entity.admin.AdminUser;
import com.newear.marathon.entity.admin.AdminUserRole;
import com.newear.marathon.mapper.AdminUserMapper;
import com.newear.marathon.mapper.AdminUserRoleMapper;
import com.newear.marathon.service.IAdminUserRoleService;
import com.newear.marathon.service.IAdminUserService;
import com.newear.marathon.utils.*;
import com.newear.marathon.vo.LeftMenuListVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser> implements IAdminUserService
{
    @Autowired
    private AdminUserMapper adminUserMapper;
    @Autowired
    private AdminUserRoleMapper adminUserRoleMapper;
    @Autowired
    private IAdminUserRoleService IAdminUserRoleService;
    @Autowired
    private BCryptPasswordEncoder encoder;
    /*@Autowired
    private MailSendProducer mailSendProducer;*/

    @Override
    public AdminUserInquiryPageResponseDTO doUserInquiryPage(AdminUserInquiryPageRequestDTO requestDTO)
    {
        log.info("doUserInquiryPage start");
        AdminUserInquiryPageResponseDTO responseDTO = new AdminUserInquiryPageResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //分页查询
        PageModel pageModel = requestDTO.getPage();
        Page<AdminUserInquiryPageResponseSubDTO> page = new Page<>(pageModel.getCurrent(), pageModel.getSize());
        page.setDesc("gmt_create");
        List<AdminUserInquiryPageResponseSubDTO> result = adminUserMapper.queryUserPage(page, requestDTO);
        //查询角色名称
        result.forEach(w -> {
            Integer userId = w.getId();
            List<AdminRole> roleList = adminUserRoleMapper.queryRoleListByUserId(userId);
            String roleNames = roleList.stream().map(x -> x.getRoleName()).collect(Collectors.joining(","));
            roleNames = StringBlankFormat.formatBlankString(roleNames);
            w.setRoleNames(roleNames);
            w.setEmail(StringBlankFormat.formatBlankString(w.getEmail()));
            w.setLastLoginTime(StringBlankFormat.formatBlankString(w.getLastLoginTime()));
            w.setLoginTime(StringBlankFormat.formatBlankString(w.getLoginTime()));
            w.setGmtCreate(StringBlankFormat.formatBlankString(w.getGmtCreate()));
        });
        pageModel.setTotal(page.getTotal());
        responseDTO.setPage(pageModel);
        responseDTO.setDataList(result);
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doUserInquiryPage end");
        return responseDTO;

    }

    @Override
    public AdminUserModifyInquiryResponseDTO doUserModifyInquiry(AdminUserModifyInquiryRequestDTO requestDTO)
    {
        log.info("doUserModifyInquiry start");
        AdminUserModifyInquiryResponseDTO responseDTO = new AdminUserModifyInquiryResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //查询用户信息
        QueryWrapper<AdminUser> wrapper = new QueryWrapper<>();
        wrapper.eq("id", requestDTO.getId());
        wrapper.select("id", "gender", "username", "mobile", "real_name", "email");
        AdminUser user = getOne(wrapper);
        if (null != user)
        {
            BeanUtils.copyProperties(user, responseDTO);
        }
        //查询用户的所有角色，并复制数据
        List<AdminRole> roleList = adminUserRoleMapper.queryRoleListByUserId(requestDTO.getId());
        List<AdminUserModifyInquiryResponseSubDTO> dataList = new ArrayList<>();
        roleList.forEach(w -> {
            AdminUserModifyInquiryResponseSubDTO responseSubDTO = new AdminUserModifyInquiryResponseSubDTO();
            BeanUtils.copyProperties(w, responseSubDTO);
            dataList.add(responseSubDTO);
        });
        responseDTO.setDataList(dataList);
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doUserModifyInquiry end");
        return responseDTO;
    }

    @Transactional
    @Override
    public AdminUserAdditionResponseDTO doUserAddition(AdminUserAdditionRequestDTO requestDTO)
    {
        log.info("doUserAddition start");
        AdminUserAdditionResponseDTO responseDTO = new AdminUserAdditionResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //判断用户名是否存在
        QueryWrapper<AdminUser> wrapper = new QueryWrapper();
        wrapper.lambda().eq(AdminUser::getUsername, requestDTO.getUsername());
        Integer count = count(wrapper);
        if (count > 0)
        {
            throw new BaseException(ApplicationError.USER_NAME_ALREADY_EXIST.getMessage(), ApplicationError.USER_NAME_ALREADY_EXIST.getCode());
        }
        //组装用户数据
        AdminUser user = new AdminUser();
        BeanUtils.copyProperties(requestDTO, user);

        //默认密码abc123
        user.setPassword(encoder.encode(Constant.defaultPassword));
        //添加操作
        Boolean result = save(user);
        if (!result)
        {
            throw new BaseException(ApplicationError.ADDITION_FAILED.getMessage(), ApplicationError.ADDITION_FAILED.getCode());
        }
        //组装用户角色数据
        List<AdminUserRole> userRoles = new ArrayList<>();
        String roles = requestDTO.getRoles();
        if (StringUtils.isNotBlank(roles))
        {
            Stream.of(roles.split(",")).filter(x -> StringUtils.isNotBlank(x)).forEach(w -> {
                AdminUserRole userRole = new AdminUserRole();
                userRole.setRoleId(Integer.parseInt(w));
                userRole.setUserId(user.getId());
                userRole.setCreateOperator(requestDTO.getCreateOperator());
                userRoles.add(userRole);
            });
        }

        //批量插入用户角色
        if (userRoles.size() > 0)
        {
            IAdminUserRoleService.doUserRoleBatchAddition(userRoles);
        }
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doUserAddition end");
        return responseDTO;
    }

    @Transactional
    @Override
    public AdminUserModifyResponseDTO doUserModify(AdminUserModifyRequestDTO requestDTO)
    {
        log.info("doUserModify start");
        AdminUserModifyResponseDTO responseDTO = new AdminUserModifyResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //判断：如果available=0，不让更新
        Integer available = getUserStatus(requestDTO.getId());
        if (1 != available)
        {
            throw new BaseException(ApplicationError.USER_NOT_UPDATE.getMessage(), ApplicationError.USER_NOT_UPDATE.getCode());
        }

        AdminUser user = new AdminUser();
        BeanUtils.copyProperties(requestDTO, user);
        //更新操作
        Boolean result = updateById(user);
        if (!result)
        {
            throw new BaseException(ApplicationError.MODIFY_FAILED.getMessage(), ApplicationError.MODIFY_FAILED.getCode());
        }
        //删除用户角色
        adminUserRoleMapper.deleteByUserId(requestDTO.getId());
        List<AdminUserRole> userRoles = new ArrayList<>();
        String roles = requestDTO.getRoles();
        if (StringUtils.isNotBlank(roles))
        {
            Stream.of(roles.split(",")).filter(x -> StringUtils.isNotBlank(x)).forEach(w -> {
                AdminUserRole userRole = new AdminUserRole();
                userRole.setRoleId(Integer.parseInt(w));
                userRole.setUserId(user.getId());
                userRole.setCreateOperator(requestDTO.getModifyOperator());
                userRoles.add(userRole);
            });
        }

        //批量插入用户角色
        if (userRoles.size() > 0)
        {
            IAdminUserRoleService.doUserRoleBatchAddition(userRoles);
        }
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doUserModify end");
        return responseDTO;
    }
    public Integer getUserStatus(Integer userId)
    {
        QueryWrapper<AdminUser> wrapper = new QueryWrapper<>();
        wrapper.eq("id", userId);
        wrapper.select("available");
        AdminUser adminUser = getOne(wrapper);
        if (null != adminUser)
        {
            return adminUser.getAvailable();
        }
        else
        {
            throw new BaseException(ApplicationError.MODIFY_FAILED.getMessage(), ApplicationError.MODIFY_FAILED.getCode());
        }
    }

    @Transactional
    @Override
    public AdminUserBaseInfoModifyResponseDTO doUserBaseInfoModify(AdminUserBaseInfoModifyRequestDTO requestDTO)
    {
        log.info("doUserBaseInfoModify start");
        AdminUserBaseInfoModifyResponseDTO responseDTO = new AdminUserBaseInfoModifyResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //组装用户数据
        AdminUser user = new AdminUser();
        BeanUtils.copyProperties(requestDTO, user);
        //更新操作
        Boolean result = updateById(user);
        if (!result)
        {
            throw new BaseException(ApplicationError.MODIFY_FAILED.getMessage(), ApplicationError.MODIFY_FAILED.getCode());
        }
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doUserBaseInfoModify end");
        return responseDTO;
    }

    @Transactional
    @Override
    public AdminUserModifyStatusResponseDTO doUserModifyStatus(AdminUserModifyStatusRequestDTO requestDTO)
    {
        log.info("doUserDelete start");
        AdminUserModifyStatusResponseDTO responseDTO = new AdminUserModifyStatusResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //组装用户数据
        AdminUser user = new AdminUser();
        BeanUtils.copyProperties(requestDTO, user);
        //更新操作
        Boolean result = updateById(user);
        if (!result)
        {
            throw new BaseException(ApplicationError.DELETE_FAILED.getMessage(), ApplicationError.DELETE_FAILED.getCode());
        }
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doUserDelete end");
        return responseDTO;
    }

    @Transactional
    @Override
    public AdminUserModifyPasswordResponseDTO doUserModifyPassword(AdminUserModifyPasswordRequestDTO requestDTO)
    {
        log.info("doUserModifyPassword start");
        AdminUserModifyPasswordResponseDTO responseDTO = new AdminUserModifyPasswordResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //判断两次密码是否一致
        if (!requestDTO.getNewPassword().equalsIgnoreCase(requestDTO.getRepeatNewPassword()))
        {
            throw new BaseException(ApplicationError.TWO_PASSWORD_ERROR.getMessage(), ApplicationError.TWO_PASSWORD_ERROR.getCode());
        }
        //判断原密码是否正确
        AdminUser user = adminUserMapper.selectById(requestDTO.getId());
        if (null == user)
        {
            throw new BaseException(ApplicationError.LOGIN_USER_ERROR.getMessage(), ApplicationError.LOGIN_USER_ERROR.getCode());
        }
        boolean checkPw = encoder.matches(requestDTO.getOldPassword(),user.getPassword());
        if (!checkPw)
        {
            throw new BaseException(ApplicationError.OLD_PASSWORD_ERROR.getMessage(), ApplicationError.OLD_PASSWORD_ERROR.getCode());
        }
        //更新密码
        AdminUser updateUser = new AdminUser();
        updateUser.setId(requestDTO.getId());
        updateUser.setPassword(encoder.encode(requestDTO.getNewPassword()));
        updateUser.setModifyOperator(user.getUsername());
        adminUserMapper.updateById(updateUser);
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doUserModifyPassword end");
        return responseDTO;
    }

    @Transactional
    @Override
    public AdminUserResetPasswordResponseDTO doUserResetPassword(AdminUserResetPasswordRequestDTO requestDTO)
    {
        log.info("doUserResetPassword start");
        AdminUserResetPasswordResponseDTO responseDTO = new AdminUserResetPasswordResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //判断ID是否存在
        QueryWrapper<AdminUser> wrapper = new QueryWrapper<>();
        wrapper.eq("id", requestDTO.getId());
        wrapper.eq("available", 1);
        wrapper.select("id", "username", "email");
        AdminUser user = getOne(wrapper);
        if (null == user)
        {
            throw new BaseException(ApplicationError.USERID_STATUS_INVALID.getMessage(), ApplicationError.USERID_STATUS_INVALID.getCode());
        }
        //重置密码
        AdminUser user2 = new AdminUser();
        user2.setId(requestDTO.getId());
        user2.setPassword(encoder.encode(Constant.defaultPassword));
        user2.setModifyOperator(requestDTO.getModifyOperator());
        updateById(user2);
        //发送邮件
        /*MailSend mailSend = new MailSend();
        mailSend.setToMail(user.getEmail());
        mailSend.setSubject("后台用户密码重置");
        mailSend.setContent("亲爱的"+user.getUserName()+"用户，您的新密码为："+user.getUserName());
        mailSend.setType(1);
        mailSendProducer.send(mailSend);*/
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doUserResetPassword end");
        return responseDTO;
    }

    @Override
    public AdminLeftMenuInquiryResponseDTO doLeftMenuInquiry(AdminLeftMenuInquiryRequestDTO requestDTO)
    {
        log.info("doLeftMenuInquiry start");
        AdminLeftMenuInquiryResponseDTO responseDTO = new AdminLeftMenuInquiryResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //查询菜单
        List<LeftMenuListVO> list = adminUserMapper.queryLeftMenu(requestDTO.getUsername());
        //查询权限列表
        List<String> permissions = getPermissions(requestDTO.getUsername());
        //循环所有资源，标记已授权的资源，并递归生成树
        List<AdminLeftMenuInquiryResponseSubDTO> responseSubDTOS = createTree(list);
        responseDTO.setDataList(responseSubDTOS);
        responseDTO.setPermissions(permissions);
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doLeftMenuInquiry end");
        return responseDTO;
    }

    @Override
    public AdminPermissionsInquiryResponseDTO doPermissionsInquiry(AdminPermissionsInquiryRequestDTO requestDTO)
    {
        log.info("doPermissionsInquiry start");
        AdminPermissionsInquiryResponseDTO responseDTO = new AdminPermissionsInquiryResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //查询权限列表
        List<String> permissions = getPermissions(requestDTO.getUsername());
        responseDTO.setPermissions(permissions);
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doPermissionsInquiry end");
        return responseDTO;
    }

    @Override
    public AdminUserBaseInfoModifyInquiryResponseDTO doUserBaseInfoModifyInquiry(AdminUserBaseInfoModifyInquiryRequestDTO requestDTO)
    {
        log.info("doUserBaseInfoModifyInquiry start");
        AdminUserBaseInfoModifyInquiryResponseDTO responseDTO = new AdminUserBaseInfoModifyInquiryResponseDTO();
        TransactionStatus transactionStatus = new TransactionStatus();
        //查询用户信息
        QueryWrapper<AdminUser> wrapper = new QueryWrapper<>();
        wrapper.eq("id", requestDTO.getId());
        wrapper.select("id", "gender", "username", "mobile", "real_name", "email");
        AdminUser user = getOne(wrapper);
        if (null != user)
        {
            BeanUtils.copyProperties(user, responseDTO);
        }
        //查询用户的所有角色，并复制数据
        List<AdminRole> roleList = adminUserRoleMapper.queryRoleListByUserId(requestDTO.getId());
        List<AdminUserModifyInquiryResponseSubDTO> dataList = new ArrayList<>();
        roleList.forEach(w -> {
            AdminUserModifyInquiryResponseSubDTO responseSubDTO = new AdminUserModifyInquiryResponseSubDTO();
            BeanUtils.copyProperties(w, responseSubDTO);
            dataList.add(responseSubDTO);
        });
        String roles = roleList.stream().map(w -> w.getRoleName()).collect(Collectors.joining(","));
        responseDTO.setRoles(roles);
        responseDTO.setTransactionStatus(transactionStatus);
        log.info("doUserBaseInfoModifyInquiry end");
        return responseDTO;
    }

    public List<String> getPermissions(String username)
    {
        List<String> permissions = adminUserMapper.queryPermissions(username);
        return permissions;
    }

    public List<AdminLeftMenuInquiryResponseSubDTO> createTree(List<LeftMenuListVO> resourceList)
    {
        List<AdminLeftMenuInquiryResponseSubDTO> list = new ArrayList<>();
        for (LeftMenuListVO resource : resourceList)
        {
            String[] levels = resource.getParentIds().split("/");
            if (levels.length == OtherConstant.MENU_LEVEL)
            {//判断是否是一级菜单
                AdminLeftMenuInquiryResponseSubDTO treeObject = new AdminLeftMenuInquiryResponseSubDTO();
                treeObject.setId(resource.getId());
                treeObject.setName(resource.getName());
                treeObject.setIcon(resource.getIcon());
                treeObject.setUrl(resource.getUrl());
                treeObject.setPriority(resource.getPriority());
                treeObject.setChildren(getChildren(resource.getId(), resourceList));
                list.add(treeObject);
            }
        }
        return list;
    }

    public List<AdminLeftMenuInquiryResponseSubDTO> getChildren(Integer parentId, List<LeftMenuListVO> resourceList)
    {
        List<AdminLeftMenuInquiryResponseSubDTO> list = new ArrayList<>();
        for (LeftMenuListVO resource : resourceList)
        {
            if (resource.getParentId().equals(parentId))
            {
                AdminLeftMenuInquiryResponseSubDTO treeObject = new AdminLeftMenuInquiryResponseSubDTO();
                treeObject.setId(resource.getId());
                treeObject.setName(resource.getName());
                treeObject.setIcon(resource.getIcon());
                treeObject.setUrl(resource.getUrl());
                treeObject.setPriority(resource.getPriority());
                treeObject.setChildren(getChildren(resource.getId(), resourceList));
                list.add(treeObject);
            }
        }
        return list;
    }

    @Override
    public AdminUser findByUsername(String username)
    {
        QueryWrapper<AdminUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        queryWrapper.eq("available", AdminStatus._1.getCode());
        return adminUserMapper.selectOne(queryWrapper);
    }
}
